package pub.developers.forum.facade.impl;

import com.alibaba.fastjson.JSON;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import pub.developers.forum.api.model.PageRequestModel;
import pub.developers.forum.api.model.PageResponseModel;
import pub.developers.forum.api.model.ResultModel;
import pub.developers.forum.api.request.AdminBooleanRequest;
import pub.developers.forum.api.request.article.ArticleInformRequest;
import pub.developers.forum.api.request.user.*;
import pub.developers.forum.api.response.article.ArticleLoveResponse;
import pub.developers.forum.api.response.follow.commentFollowResponse;
import pub.developers.forum.api.response.follow.postsFollowResponse;
import pub.developers.forum.api.response.user.UserInfoResponse;
import pub.developers.forum.api.response.user.UserOptLogPageResponse;
import pub.developers.forum.api.response.user.UserPageResponse;
import pub.developers.forum.api.service.UserApiService;
import pub.developers.forum.app.manager.ArticleManager;
import pub.developers.forum.app.manager.UserManager;
import pub.developers.forum.common.enums.ErrorCodeEn;
import pub.developers.forum.common.support.CheckUtil;
import pub.developers.forum.domain.service.OssTxtService;
import pub.developers.forum.facade.support.ResultModelUtil;
import pub.developers.forum.facade.validator.ArticleValidator;
import pub.developers.forum.facade.validator.PageRequestModelValidator;
import pub.developers.forum.facade.validator.UserValidator;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@Service
public class UserApiServiceImpl implements UserApiService {

    @Value("${spring.mail.username}")
    private String from;

    @Value("${spring.mail.nickname}")
    private String nickname;
    @Resource
    private JavaMailSender mailSender;
    @Resource
    private UserManager userManager;

    @Resource
    private ArticleManager articleManager;

    @Resource
    private OssTxtService ossTxtService;

    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @Override
    public ResultModel enable(Long uid) {
        userManager.enable(uid);

        return ResultModelUtil.success();
    }

    @Override
    public ResultModel disable(Long uid) {
        userManager.disable(uid);

        return ResultModelUtil.success();
    }

    @Override
    public ResultModel follow(Long followed) throws Exception {
        userManager.follow(followed);

        return ResultModelUtil.success();
    }

    @Override
    public ResultModel cancelFollow(Long followed) throws Exception {
        userManager.cancelFollow(followed);

        return ResultModelUtil.success();
    }

    @Override
    public ResultModel<PageResponseModel<UserPageResponse>> pageFollower(PageRequestModel<Long> pageRequestModel) {
        PageRequestModelValidator.validator(pageRequestModel);
        pageRequestModel.setFilter(JSON.parseObject(JSON.toJSONString(pageRequestModel.getFilter()), Long.class));

        return ResultModelUtil.success(userManager.pageFollower(pageRequestModel));
    }

    @Override
    public ResultModel<PageResponseModel<UserPageResponse>> pageFans(PageRequestModel<Long> pageRequestModel) {
        PageRequestModelValidator.validator(pageRequestModel);
        pageRequestModel.setFilter(JSON.parseObject(JSON.toJSONString(pageRequestModel.getFilter()), Long.class));

        return ResultModelUtil.success(userManager.pageFans(pageRequestModel));
    }

    @Override
    public ResultModel<Boolean> hasFollow(Long followed) {
        return ResultModelUtil.success(userManager.hasFollow(followed));
    }

    @Override
    public ResultModel<UserInfoResponse> info(String token) {
        return ResultModelUtil.success(userManager.info(token));
    }

    @Override
    public ResultModel<UserInfoResponse> info(Long uid) {
        return ResultModelUtil.success(userManager.info(uid));
    }

    @Override
    public ResultModel<String> register(UserRegisterRequest request) throws Exception {
        UserValidator.register(request);

        //用户昵称审核
        List<Map<String , String>> result = ossTxtService.checkText(request.getNickname());
        if ("block".equals(result.get(0).get("suggestion"))) {
            //用户昵称审核不通过
            return ResultModelUtil.fail(ErrorCodeEn.NickName_IS_NOPASS);
        }

        return ResultModelUtil.success(userManager.register(request));
    }

    @Override
    public ResultModel<String> emailLogin(UserEmailLoginRequest request) throws Exception {
        UserValidator.emailLogin(request);

        return ResultModelUtil.success(userManager.emailRequestLogin(request));
    }

    public ResultModel<String> wxLogin(String openid) throws Exception {
        return ResultModelUtil.success(userManager.wxRequestLogin(openid));
    }

    public ResultModel<String> wxLogin(UserWxLoginRequest request) throws Exception {
        return ResultModelUtil.success(userManager.wxRequestLogin(request));
    }

    // 删除emoji
    public static String removeEmoji(String username) {
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < username.length(); ) {
            int codePoint = username.codePointAt(i);

            if (!isEmoji(codePoint)) {
                result.appendCodePoint(codePoint);
            }

            i += Character.charCount(codePoint);
        }

        return result.toString();
    }

    // 判断emoji
    public static boolean isEmoji(int codePoint) {
        // Emoji Unicode范围：\uD83C\uDF00 - \uD83D\uDFFF
        return (codePoint >= 0x1F300 && codePoint <= 0x1F64F) ||
                (codePoint >= 0x1F680 && codePoint <= 0x1F6FF) ||
                (codePoint >= 0x1F700 && codePoint <= 0x1F77F) ||
                (codePoint >= 0x1F780 && codePoint <= 0x1F7FF) ||
                (codePoint >= 0x1F800 && codePoint <= 0x1F8FF) ||
                (codePoint >= 0x1F900 && codePoint <= 0x1F9FF) ||
                (codePoint >= 0x1FA00 && codePoint <= 0x1FA6F) ||
                (codePoint >= 0x1FA70 && codePoint <= 0x1FAFF);
    }

    @Override
    public ResultModel logout(UserTokenLogoutRequest request) throws Exception {
        UserValidator.logout(request);

        userManager.logout(request);

        return ResultModelUtil.success();
    }

    public ResultModel signOut(){
        userManager.signOut();
        return ResultModelUtil.success();
    }

    @Override
    public ResultModel updateInfo(UserUpdateInfoRequest request) throws UnsupportedEncodingException {
        UserValidator.updateInfo(request); //检查参数

        StringBuilder sb = new StringBuilder();
        sb.append(request.getNickname());
        if( request.getAddress() != null )
        {
            sb.append(request.getAddress());
        }
        if ( request.getSignature() != null )
        {
            sb.append(request.getSignature());
        }

        //审核用户的个性签名 以及家庭住址
        List<Map<String , String>> result = ossTxtService.checkText(sb.toString());
        if ("block".equals(result.get(0).get("suggestion"))) {
            //用户昵称审核不通过
            return ResultModelUtil.fail(ErrorCodeEn.Information_IS_NOPASS);
        }
        //拿到openid 判断登录时的方式
        String openID = userManager.getOpenId();
        //如果openid 为空说明是邮箱登录
        if(openID.isEmpty())
        {
            //如果是邮箱登录方式,邮箱需要作为一个必传字段
            UserValidator.updateInfo2(request);
            userManager.updateInfo(request);
        }
        else
        {
            //如果是微信登录方式,不需要校验邮箱
            userManager.updateInfo(request);
        }
        return ResultModelUtil.success();
    }
    @Override
    public ResultModel updateHeadImg(String linkFilenameData) {


        userManager.updateHeadimg(linkFilenameData);

        return ResultModelUtil.success();
    }

    @Override
    public ResultModel updatePwd(UserUpdatePwdRequest request) {
        UserValidator.updatePwd(request);

        userManager.updatePwd(request);

        return ResultModelUtil.success();
    }

    @Override
    public ResultModel<PageResponseModel<UserPageResponse>> adminPage(PageRequestModel<UserAdminPageRequest> pageRequestModel) {
        PageRequestModelValidator.validator(pageRequestModel);
        UserAdminPageRequest request = JSON.parseObject(JSON.toJSONString(pageRequestModel.getFilter()), UserAdminPageRequest.class);
        UserValidator.adminPage(request);
        pageRequestModel.setFilter(request);

        return ResultModelUtil.success(userManager.page(pageRequestModel));
    }

    @Override
    public ResultModel<PageResponseModel<UserPageResponse>> pageActive(PageRequestModel pageRequestModel) {
        return ResultModelUtil.success(userManager.pageActive(pageRequestModel));
    }

    @Override
    public ResultModel<PageResponseModel<UserOptLogPageResponse>> pageOptLog(PageRequestModel<UserOptLogPageRequest> pageRequestModel) {
        PageRequestModelValidator.validator(pageRequestModel);
        UserOptLogPageRequest request = JSON.parseObject(JSON.toJSONString(pageRequestModel.getFilter()), UserOptLogPageRequest.class);
        pageRequestModel.setFilter(request);

        return ResultModelUtil.success(userManager.pageOptLog(pageRequestModel));
    }

    @Override
    public ResultModel updateRole(AdminBooleanRequest booleanRequest) {
        ArticleValidator.validatorBooleanRequest(booleanRequest);

        userManager.updateRole(booleanRequest);

        return ResultModelUtil.success();
    }


    //获取用户自己的粉丝列表
    @Override
    public ResultModel<List<UserInfoResponse>> queryFans() {
        return ResultModelUtil.success(userManager.querySelfFans());
    }

    public ResultModel<PageResponseModel<UserInfoResponse>> queryFollower(PageRequestModel pageRequestModel){
        return ResultModelUtil.success(userManager.querySelfFollower(pageRequestModel.getFilter(), pageRequestModel.getPageSize() , pageRequestModel.getPageNo()));
    }

    //获取点赞消息 , 谁给我的帖子点赞了
    @Override
    public ResultModel<List<postsFollowResponse>> queryFollowList() {
        return ResultModelUtil.success(userManager.queryFollowContent());
    }

    //获取点赞消息 , 谁给我的评论点赞了
    @Override
    public ResultModel<List<commentFollowResponse>> queryFollowCommentList() {
        return ResultModelUtil.success(userManager.queryFollowCommentListManager());
    }

    //发送邮件
    public void sendEmail(String to,String title,String content , String code){
        try {
            // 获得模板
            Template template1 = freeMarkerConfigurer.getConfiguration().getTemplate("email.html");
            // 使用Map作为数据模型，定义属性和值
            Map<String,Object> model = new HashMap<>();
            model.put("content",content);
            // 传入数据模型到模板，替代模板中的占位符，并将模板转化为html字符串
            String templateHtml = FreeMarkerTemplateUtils.processTemplateIntoString(template1,model);
            //注意这里使用的是MimeMessage
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(nickname+'<'+from+'>');
            helper.setTo(to);
            helper.setSubject(title);
            helper.setText(templateHtml , true);
            mailSender.send(message);
            log.info("邮件发送成功");
            //将验证码存储到redis数据库中
            /*
            to:接收验证码的邮箱
            code : 验证码
            */
            userManager.saveEmailCode(to , code);
        } catch (TemplateException e) {
            log.error("发送邮件时发生异常！", e);
        } catch (IOException e) {
            log.error("发送邮件时发生异常！", e);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }

    //邮箱登录
    public ResultModel<String> emailLogin(UserRegisterRequest userRegisterRequest) throws Exception {
        CheckUtil.checkParamToast(userRegisterRequest , "request");
        CheckUtil.checkParamToast(userRegisterRequest.getCode() , "code");

        return ResultModelUtil.success(userManager.emailCodeLoginManager(userRegisterRequest));
    }

    //用户查看自己的个人信息
    @Override
    public ResultModel<UserInfoResponse> querySelfInformation(Long userId) {

        return ResultModelUtil.success(userManager.querySelfInformationManager(userId));
    }


    //查看用户上传的头像的数量
    @Override
    public ResultModel<Boolean> queryAvatarCountService()
    {
        return ResultModelUtil.success(userManager.queryImgCount());
    }

    //用户上传头像功能3
    @Override
    public ResultModel<String> uploadAvatar3(String avatar) {
        return ResultModelUtil.success(userManager.updateAvatar3(avatar));
    }

    //用户删除指定图片
    public ResultModel deleteAvatar(String deleteAvatar)
    {
        userManager.deleteAvatar(deleteAvatar);
        return ResultModelUtil.success();
    }

    //查询用户头像是否重复
    public ResultModel<Boolean> selectSameAvatar(String avatar)
    {
        return ResultModelUtil.success(userManager.getSameAvatar(avatar));
    }

    //获取我点赞的帖子
    @Override
    public ResultModel<PageResponseModel<ArticleLoveResponse>> selectMyLovePosts(Integer pageNo , Integer pageSize) throws Exception {
        return ResultModelUtil.success(articleManager.queryMyLovePosts(pageNo , pageSize));
    }

    //用户举报帖子
    @Override
    public ResultModel userInformPosts(ArticleInformRequest articleInformRequest) {
        ArticleValidator.informArticle(articleInformRequest);
        articleManager.addInform(articleInformRequest);
        return ResultModelUtil.success();
    }

    @Override
    public ResultModel deleteUser(Long id) {
        userManager.deleteUserManager(id);
        return ResultModelUtil.success();
    }

}
